#include "cansetmodel.h"
#include <QDebug>

static const UINT kAbitTiming[] = {
    0x00018B2E,//1Mbps
    0x00018E3A,//800kbps
    0x0001975E,//500kbps
    0x0001AFBE,//250kbps
    0x0041AFBE,//125kbps
    0x0041BBEE,//100kbps
    0x00C1BBEE //50kbps
};
static const UINT kDbitTiming[] = {
    0x00010207,//5Mbps
    0x0001020A,//4Mbps
    0x0041020A,//2Mbps
    0x0081830E //1Mbps
};
static const BYTE kTiming0[] = {
    0x00,//1000kbps
    0x00,//800kbps
    0x00,//500kbps
    0x01,//250kbps
    0x03,//125kbps
    0x04,//100kbps
    0x09,//50kbps
    0x18,//20kbps
    0x31,//10kbps
    0xBF //5kbps
};
static const BYTE kTiming1[] = {
    0x14,//1000kbps
    0x16,//800kbps
    0x1C,//500kbps
    0x1C,//250kbps
    0x1C,//125kbps
    0x1C,//100kbps
    0x1C,//50kbps
    0x1C,//20kbps
    0x1C,//10kbps
    0xFF //5kbps
};
static const unsigned kBaudrate[] = {
    1000000,
    800000,
    500000,
    250000,
    125000,
    100000,
    50000,
    20000,
    10000,
    5000
};

CanSetModel::CanSetModel(QObject *parent) : QObject(parent)
{

}

void CanSetModel::SetPara(int type, int index, char *br)
{
    this->DeviceType = type;
    this->DeveiceIndex = index;
    this->BaudRate = br;
    this->BaudRateFd = br;
}

void CanSetModel::DataReceive()
{
    ZCAN_Receive_Data can_data[100];
    ZCAN_ReceiveFD_Data canfd_data[100];
    UINT len;
    while(isStart)
    {
        if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CAN))
        {
            len = ZCAN_Receive(chHandle, can_data, 100, 50);
            AddData(can_data, len);
        }
        if (len = ZCAN_GetReceiveNum(chHandle, TYPE_CANFD))
        {
            len = ZCAN_ReceiveFD(chHandle, canfd_data, 100, 50);
            AddData(canfd_data, len);
        }
    }
}

void CanSetModel::AddData(const ZCAN_Receive_Data *data, UINT len)
{
    QString item;
    for (UINT i = 0; i < len; ++i)
    {
        const ZCAN_Receive_Data& can = data[i];
        const canid_t& id = can.frame.can_id;

        CanDataBase *cdb = new CanDataBase();
        cdb->SetTime(data->timestamp);
        cdb->SetData(GET_ID(id),(unsigned char*)can.frame.data,can.frame.can_dlc,IS_EFF(id),IS_RTR(id));

        AddData(cdb);
    }
}

void CanSetModel::AddData(const ZCAN_ReceiveFD_Data *data, UINT len)
{
    QString item;
    for (UINT i = 0; i < len; ++i)
    {
        const ZCAN_ReceiveFD_Data& canfd = data[i];
        const canid_t& id = canfd.frame.can_id;

        CanDataBase *cdb = new CanDataBase();
        cdb->SetTime(data->timestamp);

        cdb->SetData(GET_ID(id),(unsigned char*)canfd.frame.data,canfd.frame.len,IS_EFF(id),IS_RTR(id));

        AddData(cdb);
    }
}

void CanSetModel::AddData(CanDataBase *cdb)
{
    cdb->SetTime(QDateTime::currentDateTime());
    cdb->GetStringData();
   // qDebug()<<"ID:" <<cdb->Id<<"数据："<<cdb->StrData;

    emit this->DataUpdata(cdb);
}


bool CanSetModel::CanConnect()
{
    bool isCanFd = false;

    if(DeviceType == ZCAN_USBCANFD_200U || DeviceType == ZCAN_USBCANFD_100U || DeviceType == ZCAN_USBCANFD_MINI)
        isCanFd = true;

    //ZCAN_USBCAN_2E_U为设备类型,  请根据实际修改
    dhandle = ZCAN_OpenDevice(DeviceType, DeveiceIndex, 0);
    if (INVALID_DEVICE_HANDLE == dhandle)
    {
        qDebug( "打开设备失败" );
        return false;
    }
    IProperty* property = GetIProperty(dhandle);
    if (NULL == property)
    {
        qDebug()<< "属性指针为空" ;
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        return false;
    }

    ZCAN_CHANNEL_INIT_CONFIG cfg;
    if(isCanFd)
    {
        //仲裁域波特率
        if (property->SetValue("0/canfd_abit_baud_rate",BaudRateFd ) != STATUS_OK)
        {
            qDebug() << "设置波特率失败" ;
            ReleaseIProperty(property);
            ZCAN_CloseDevice(dhandle);
            return false;
        }

        // 数据域波特率
        if (property->SetValue("0/canfd_dbit_baud_rate", BaudRate) != STATUS_OK)
        {
            qDebug() << "设置波特率失败" ;
            ReleaseIProperty(property);
            ZCAN_CloseDevice(dhandle);
            return false;
        }

        memset(&cfg, 0, sizeof(cfg));
        cfg.can_type = TYPE_CANFD;//CANFD设备为TYPE_CANFD
        cfg.can.filter = 0;
        cfg.can.mode = 0; //正常模式, 1为只听模式
        cfg.can.acc_code = 0;
        cfg.can.acc_mask = 0xffffffff;
    }
    else
    {
        if (property->SetValue("0/baud_rate", BaudRate) != STATUS_OK)
        {
            qDebug() << "设置波特率失败" ;
            ReleaseIProperty(property);
            ZCAN_CloseDevice(dhandle);
            return false;
        }

        memset(&cfg, 0, sizeof(cfg));
        cfg.can_type = TYPE_CAN;//CANFD设备为TYPE_CANFD
        cfg.can.filter = 0;
        cfg.can.mode = 0; //正常模式, 1为只听模式
        cfg.can.acc_code = 0;
        cfg.can.acc_mask = 0xffffffff;
    }

    chHandle = ZCAN_InitCAN(dhandle, 0, &cfg);
    if (INVALID_CHANNEL_HANDLE == chHandle)
    {
        qDebug() << "初始化通道失败";
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        return false;
    }
    if (ZCAN_StartCAN(chHandle) != STATUS_OK)
    {
        qDebug() << "启动通道失败" ;
        ReleaseIProperty(property);
        ZCAN_CloseDevice(dhandle);
        return false;
    }

    isStart =true;

    return true;

}

void CanSetModel::CanClose()
{
    // ReleaseIProperty(property);
    ZCAN_CloseDevice(dhandle);

    isStart = false;
}

bool CanSetModel::CanSend(CanDataBase *data)
{

    ZCAN_Transmit_Data frame;
    memset(&frame, 0, sizeof(frame));


    frame.frame.can_id = data->Id ;
    frame.frame.can_dlc =data->Len;
    for( int i = 0; i < data->Len; i++ )
    {
        frame.frame.data[i] =  data->Data[i];
    }

    if (ZCAN_Transmit(chHandle, &frame, 1) != 1)
    {
        qDebug() << "发送数据失败" ;
        return false;
    }

   // data->sTime = frame.

    return true;
}
